import type { Response } from 'express'

import { Context } from '@/types'
import { ExtendedRequestWithPageInfo } from '@/article-api/types'
import contextualize from '@/frame/middleware/context/context'
import { transformerRegistry } from '@/article-api/transformers'
import { allVersions } from '@/versions/lib/all-versions'
import type { Page } from '@/types'

/**
 * Creates a mocked rendering request and contextualizes it.
 * This is used to prepare a request for rendering pages in markdown format.
 */
async function createContextualizedRenderingRequest(pathname: string, page: Page) {
  const mockedContext: Context = {}
  const renderingReq = {
    path: pathname,
    language: page.languageCode,
    pagePath: pathname,
    cookies: {},
    context: mockedContext,
    headers: {
      'content-type': 'text/markdown',
    },
  }

  // contextualize the request to get proper version info
  await contextualize(renderingReq as ExtendedRequestWithPageInfo, {} as Response, () => {})
  renderingReq.context.page = page

  return renderingReq
}

export async function getArticleBody(req: ExtendedRequestWithPageInfo) {
  // req.pageinfo is set from pageValidationMiddleware and pathValidationMiddleware
  // and is in the ExtendedRequestWithPageInfo
  const { page, pathname, archived } = req.pageinfo

  if (archived?.isArchived)
    throw new Error(`Page ${pathname} is archived and can't be rendered in markdown.`)

  // Extract apiVersion from query params if provided
  const apiVersion = req.query.apiVersion as string | undefined

  // Check if there's a transformer for this page type (e.g., REST, webhooks, etc.)
  const transformer = transformerRegistry.findTransformer(page)

  if (transformer) {
    // Use the transformer for autogenerated pages
    const renderingReq = await createContextualizedRenderingRequest(pathname, page)

    // Determine the API version to use (provided or latest)
    // Validation is handled by apiVersionValidationMiddleware
    const currentVersion = renderingReq.context.currentVersion
    let effectiveApiVersion = apiVersion

    // Use latest version if not provided
    if (!effectiveApiVersion && currentVersion && allVersions[currentVersion]) {
      effectiveApiVersion = allVersions[currentVersion].latestApiVersion || undefined
    }

    return await transformer.transform(page, pathname, renderingReq.context, effectiveApiVersion)
  }

  // For regular articles (non-autogenerated)
  if (page.documentType !== 'article') {
    throw new Error(`Page ${pathname} isn't yet available in markdown.`)
  }

  // these parts allow us to render the page
  const renderingReq = await createContextualizedRenderingRequest(pathname, page)
  renderingReq.context.markdownRequested = true
  return await page.render(renderingReq.context)
}
